<?php

namespace helper;

use helper\calc\Parser;

class Arr
{

    /**
     * 重置数组索引，兼容多维数组
     * @param $array
     * @return array
     */
    static public function resetKeys($array)
    {
        if (!is_array($array)) return $array;
        $keys = implode('', array_keys($array));
        if (is_numeric($keys)) $array = array_values($array);
        return array_map(array(__CLASS__, "resetKeys"), $array);
    }

    /**
     * 按指定字段分组
     * @param $arr
     * @param $key
     * @param int $deep
     * @return array
     */
    static public function group($arr, $key,$deep=2)
    {
        $itemList = [];
        foreach ($arr as $v) {
            if($deep==2){
                $itemList[$v[$key]][] = $v;
            } else {
                $itemList[$v[$key]] = $v;
            }
        }
        return $itemList;
    }

    /**
     * 多维数组排序
     * @param array $arrays 需要操作的数组
     * @param string $sort_key 排序键名
     * @param int $sort_order 排序方式
     * @param int $sort_type 排序方式
     * @return array|bool 排序后的数组
     */
    static public function sort($arrays, $sort_key, $sort_order = SORT_ASC, $sort_type = SORT_NUMERIC)
    {
        if (is_array($arrays)) {
            foreach ($arrays as $array) {
                if (is_array($array)) {
                    $key_arrays[] = $array[$sort_key];
                } else {
                    return false;
                }
            }
        } else {
            return false;
        }
        array_multisort($key_arrays, $sort_order, $sort_type, $arrays);
        return $arrays;
    }

    /**
     * 二维数组指定字段最大或者最小
     * @param $arrays
     * @param $field
     * @param string $type
     * @return string|array
     */
    static public function most($arrays, $field, $type = 'max')
    {
        $arr = array_column($arrays,$field);
        if($type == 'min') return min($arr);
        if($type == 'range') return ['max'=>max($arr),'min'=>min($arr)];
        return max($arr);
    }

    /**
     * 计算指定二维数组里面某个字段的总和
     * @param array $array 数组
     * @param string $coloum 指定字段 可以使用表达式如:{goods_num}-{send_num}
     * @return float
     */
    static public function sum(array $array, string $coloum)
    {
        if(strpos($coloum,'{') !== false){
            $ret = Utils::extractBetween($coloum);
            $total = 0;
            $key = $ret[0];
            $count = count($key);
            foreach($array as $v){
                $val = [];
                for($i=0;$i<$count;$i++){
                    $val[] = $v[$ret[1][$i]];
                }
                $total += Parser::parse(str_replace($key,$val,$coloum));
            }
            return $total;
        }else{
            return array_sum(array_column($array, $coloum));
        }
    }

    /**
     * 数值区间查找索引
     * @param $arrNum
     * @param $num
     * @return false|int|string
     */
    static public function findIndex($arrNum, $num)
    {
        array_push($arrNum, $num);
        $data = array_unique($arrNum);
        sort($data);
        return array_search($num, $data);
    }

    /**
     * 格式化数组
     * @param $var
     * @return false|string
     */
    static public function arr2export($var)
    {
        $exporter = function ($var, $indent = "") use (&$exporter) {
            switch (gettype($var)) {
                case "string":
                    return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
                case "array":
                    $self    = $exporter;
                    $indexed = array_keys($var) === range(0, count($var) - 1);
                    $r       = [];
                    foreach ($var as $key => $value) {
                        $r[] = "$indent    "
                               . ($indexed ? "" : $self($key) . " => ")
                               . $self($value, "$indent    ");
                    }
                    return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
                case "boolean":
                    return $var ? "TRUE" : "FALSE";
                default:
                    return var_export($var, true);
            }
        };
        ob_start();
        array_map(function ($var) use ($exporter) {
            echo $exporter($var);
        }, func_get_args());
        $arr = ob_get_contents();
        ob_end_clean();
        return $arr;
    }

}